package com.wzz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzz.mapper.UserMapper;
import com.wzz.pojo.User;
import com.wzz.service.UserService;
import com.wzz.utile.DuanxinUtil;
import com.wzz.vo.R;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author DarkClown
 * @date 2024-08-12 09:19
 * @project_name day0812-month
 * @parem
 **/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    UserMapper userMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public R login(User user, Integer id) {
        //验证码登录
        if (id==0){
            return login1(user);
        }
        if (id==1){
            return login2(user);
        }
        return null;
    }

    @Override
    public R sendCode(User user) {
        //生成验证码
        String code = RandomUtil.randomNumbers(4);



        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        opsForValue.set("code"+user.getMobile(),code,1, TimeUnit.MINUTES);
        DuanxinUtil.sendDuanxin(user.getMobile(), code);
        return R.OK(code);


    }

    @Override
    public R updatePassword(User user) {
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        String code = opsForValue.get("code" + user.getMobile());

        if (!code.equals(user.getCode())){

            return R.ERROR(404,"验证码不正确,请重新输入");

        }
        String bcrypt = DigestUtil.bcrypt(user.getPassword());
        System.out.println("加密密码为:"+bcrypt);

        user.setPassword(bcrypt);

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        queryWrapper.lambda().le(User::getMobile,user.getMobile());

        userMapper.update(user,queryWrapper);

        return R.OK("修改成功");

    }

    //用户名密码登录
    private R login2(User user) {

        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        String bcrypt = DigestUtil.bcrypt(user.getPassword());
        System.out.println("加密密码为:"+bcrypt);
        User user1 = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getMobile, user.getMobile()));

        if (BeanUtil.isEmpty(user1)){
            return R.ERROR(404,"没有该用户");
        }

        boolean b = DigestUtil.bcryptCheck(user.getPassword(), user1.getPassword());

        if (!b){
            return R.ERROR(404,"登录失败,密码不正确");
        }

        //存储ID和角色信息
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "123456")
                .claim("uid", user1.getUid())
                .claim("username", user1.getUsername())
                .claim("mobile", user1.getMobile())
                .compact();

        opsForValue.set("token"+user.getUid(),token,1,TimeUnit.MINUTES);

        return R.OK(token);


    }
    //验证码登录
    private R login1(User user) {

        User user1 = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getMobile, user.getMobile()));

        if (BeanUtil.isEmpty(user1)){
            return R.ERROR(404,"没有该用户");
        }

        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();

        String code = opsForValue.get("code"+user.getMobile());

        if(!user.getCode().equals(code)){
            return R.ERROR(404,"验证码错误");
        }
        //生成token
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "123456")
                .claim("uid", user1.getUid())
                .claim("username", user1.getUsername())
                .claim("mobile", user1.getMobile())
                .compact();

        opsForValue.set("token"+user.getUid(),token,20,TimeUnit.MINUTES);

        return R.OK(token);
    }
}
